#include <SPI.h>
#include <Dhcp.h>
#include <Dns.h>
#include <Ethernet.h>
#include <EthernetClient.h>
#include <EthernetServer.h>
#include <EthernetUdp.h>
#include <util.h>
#include <DmxSimple.h>

int patch[50];

/*
groupes :
1 : face
2: coté
3: solo
4: retro
5 : sol-fond
6 : sol-face
7 : decoupe
*/
int groups[50];


int groupsFlags = 0x0000;

#define GROUP_1    0x0001
#define GROUP_2    0x0002
#define GROUP_3    0X0004
#define GROUP_4    0x0008
#define GROUP_5    0x0010
#define GROUP_6    0x0020
#define GROUP_7    0x0040
#define GROUP_8    0x0080
#define GROUP_9    0x0100
#define GROUP_10   0x0200
#define GROUP_11   0x0400


int DMX_dir = 4;
int LED2 = 8;
byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xEE };
IPAddress ip(192, 168, 1, 4);
IPAddress bcastIp(192, 168, 1, 255);

unsigned int ledPort = 8000;
unsigned int commandPort = 8002;

EthernetUDP UdpLed;
EthernetUDP UdpCommand;

char ledBuffer[100]; //buffer to hold incoming packet,
char commandBuffer[100]; //buffer to hold incoming packet,

char ledPower = 0;

void initPatch(){
  for (int i=0; i < 50; i++){
    patch[i] = -1; 
  }
  patch[1] = 2;
  patch[2] = 4;
  patch[3] = 3;
  patch[4] = 25;
  patch[5] = 30;
  patch[6] = 27;
  patch[7] = 21;
  patch[8] = 23;
  patch[9] = 20;
  patch[10] = 24;
  patch[11] = 22;
  patch[12] = 12;
  patch[13] = 28;
  patch[14] = 26;
  patch[15] = 10;
  patch[16] = 7;
  patch[17] = 14;
  patch[18] = 15;
  patch[19] = -1;
  patch[20] = 16;
  patch[21] = 9;
  patch[22] = 11;
  patch[23] = 13;
  patch[24] = 17;
  patch[25] = 18;
  patch[26] = 31;
  patch[27] = 32;
  patch[28] = 19;
  patch[29] = 29;
}

void initGroups(){
  for (int i=0; i < 50; i++){
    groups[i] = -1; 
  }
  //groups[1] = ;
  groups[2] = -1;
  groups[3] = -1;
  groups[4] = -1;
  groups[5] = 2;
  groups[6] = 3;
  groups[7] = -1;
  groups[8] = -1;
  groups[9] = -1;
  groups[10] = -1;
  groups[11] = 6;
  groups[12] = 6;
  groups[13] = 11;
  groups[14] = 11;
  groups[15] = 11;
  groups[16] = 11;
  groups[17] = 4;
  groups[18] = 10;
  //groups[19] = 5;
  groups[20] = 9;
  groups[21] = -1;
  groups[22] = -1;
  groups[23] = 5;
  groups[24] = 5;
  groups[25] = 5;
  groups[26] = 7;
  groups[27] = 8;
  groups[28] = 1;
}

void setup() {
  
  initGroups();
  initPatch();
  
  pinMode(DMX_dir, OUTPUT);    
  pinMode(LED2, OUTPUT);       
     
  
  digitalWrite(DMX_dir, HIGH);  // Set direction pin of trasnsceiver to Tx.
  
  /* The most common pin for DMX output is pin 3, which DmxSimple
  ** uses by default. If you need to change that, do it here. */
  DmxSimple.usePin(2);
  //DmxSimple.(LAAAAAAAAAA);

  /* DMX devices typically need to receive a complete set of channels
  ** even if you only need to adjust the first channel. You can
  ** easily change the number of channels sent here. If you don't
  ** do this, DmxSimple will set the maximum channel number to the
  ** highest channel you DmxSimple.write() to. */
  DmxSimple.maxChannel(50);
  Serial.begin(9600);
  
  Ethernet.begin(mac, ip);
  UdpCommand.begin(commandPort);
  UdpLed.begin(ledPort);
}

void loop(){
  for (int i=0; i < 50; i++){
    
    if(patch[i] == -1 || groups[i] == -1){
      
    } else {
    switch(groups[i]){
      case 1:
        if ( groupsFlags & GROUP_1){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 2:
        if ( groupsFlags & GROUP_2){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 3:
        if ( groupsFlags & GROUP_3){
          Serial.println(patch[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        } 
      break;
      case 4:
        if ( groupsFlags & GROUP_4){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 5: //sol fond
        if ( groupsFlags & GROUP_5){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 6:
        if ( groupsFlags & GROUP_6){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 7:
        if ( groupsFlags & GROUP_7){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 8:
        if ( groupsFlags & GROUP_8){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 9:
        if ( groupsFlags & GROUP_9){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 10:
        if ( groupsFlags & GROUP_10){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
      case 11:
        if ( groupsFlags & GROUP_11){
          //Serial.println(groups[i]);
          DmxSimple.write(patch[i], ledPower); 
        } else {
          DmxSimple.write(patch[i], 0); 
        }
      break;
    }
    }
    
  }
  
  //on récupère la valeur de la LED
  
  int packetSize = UdpLed.parsePacket();
  if(packetSize)
  {
    UdpLed.read(ledBuffer,100);
    ledPower = ledBuffer[0];
  }
  
  //on récupère la dernière commande
  
   packetSize = UdpCommand.parsePacket();
  if(packetSize)
  {
    UdpCommand.read(commandBuffer,100);
    Serial.print("received command : ");
    Serial.println(commandBuffer);
    switch(commandBuffer[0]){
      case 'z':
        groupsFlags = groupsFlags ^ GROUP_1;
      break;
      case 'e':
        groupsFlags = groupsFlags ^ GROUP_2;
      break;
      case 'r':
        groupsFlags = groupsFlags ^ GROUP_3;
      break;
      case 't': 
        groupsFlags = groupsFlags ^ GROUP_4;
      break;
      case 'y':
        groupsFlags = groupsFlags ^ GROUP_5;    
      break;
      case 'u':
        groupsFlags = groupsFlags ^ GROUP_6;
      break;
      case 'i':
        groupsFlags = groupsFlags ^ GROUP_7;      
      break; 
      case 'o':
        groupsFlags = groupsFlags ^ GROUP_8;      
      break; 
      case 'p':
        groupsFlags = groupsFlags ^ GROUP_9;      
      break; 
      case 'q':
        groupsFlags = groupsFlags ^ GROUP_10;      
      break; 
      case 's':
        groupsFlags = groupsFlags ^ GROUP_11;      
      break; 
    }
      
      
  }
  
  delay(10);
  
}

